// 书签管理路由
import { Router } from 'express'
import Joi from 'joi'
import { prisma } from '../lib/prisma'
import { CacheManager } from '../lib/memory-cache'
import { asyncHandler, createError } from '../middleware/error-handler'
import { authenticate } from '../middleware/auth'

const router = Router()

// 所有路由都需要认证
router.use(authenticate)

// 验证模式
const createBookmarkSchema = Joi.object({
  title: Joi.string().max(200).required().messages({
    'string.max': '标题不能超过200个字符',
    'any.required': '标题是必填项'
  }),
  url: Joi.string().uri().required().messages({
    'string.uri': 'URL格式不正确',
    'any.required': 'URL是必填项'
  }),
  iconUrl: Joi.string().uri().optional().allow('').messages({
    'string.uri': '图标URL格式不正确'
  }),
  category: Joi.string().max(50).optional().messages({
    'string.max': '分类不能超过50个字符'
  })
})

const updateBookmarkSchema = Joi.object({
  title: Joi.string().max(200).optional().messages({
    'string.max': '标题不能超过200个字符'
  }),
  url: Joi.string().uri().optional().messages({
    'string.uri': 'URL格式不正确'
  }),
  iconUrl: Joi.string().uri().optional().allow('').messages({
    'string.uri': '图标URL格式不正确'
  }),
  category: Joi.string().max(50).optional().messages({
    'string.max': '分类不能超过50个字符'
  })
})

const updateOrderSchema = Joi.object({
  bookmarks: Joi.array().items(
    Joi.object({
      id: Joi.string().required(),
      sortOrder: Joi.number().integer().min(0).required()
    })
  ).required().messages({
    'any.required': '书签列表是必填项'
  })
})

// 获取用户书签
router.get('/', asyncHandler(async (req, res) => {
  const userId = req.user!.id
  const { category, search, limit, offset } = req.query
  
  // 构建缓存键
  const cacheKey = CacheManager.getBookmarksCacheKey(userId) + 
    (category ? `:cat:${category}` : '') + 
    (search ? `:search:${search}` : '') +
    (limit ? `:limit:${limit}` : '') +
    (offset ? `:offset:${offset}` : '')
  
  // 尝试从缓存获取
  let bookmarks = await CacheManager.get(cacheKey)
  
  if (!bookmarks) {
    // 构建查询条件
    const where: any = { userId }
    
    if (category) {
      where.category = category as string
    }
    
    if (search) {
      where.OR = [
        { title: { contains: search as string } },
        { url: { contains: search as string } }
      ]
    }
    
    // 查询书签
    bookmarks = await prisma.bookmark.findMany({
      where,
      select: {
        id: true,
        title: true,
        url: true,
        iconUrl: true,
        category: true,
        sortOrder: true,
        createdAt: true,
        updatedAt: true
      },
      orderBy: [
        { sortOrder: 'asc' },
        { createdAt: 'desc' }
      ],
      take: limit ? parseInt(limit as string) : undefined,
      skip: offset ? parseInt(offset as string) : undefined
    })
    
    // 缓存5分钟
    await CacheManager.set(cacheKey, bookmarks, 300)
  }

  res.json({
    bookmarks,
    total: (bookmarks as any[]).length
  })
}))

// 获取单个书签
router.get('/:id', asyncHandler(async (req, res) => {
  const { id } = req.params
  const userId = req.user!.id
  
  const bookmark = await prisma.bookmark.findFirst({
    where: {
      id,
      userId
    },
    select: {
      id: true,
      title: true,
      url: true,
      iconUrl: true,
      category: true,
      sortOrder: true,
      createdAt: true,
      updatedAt: true
    }
  })

  if (!bookmark) {
    throw createError.notFound('书签不存在')
  }

  res.json({
    bookmark
  })
}))

// 创建书签
router.post('/', asyncHandler(async (req, res) => {
  // 验证请求数据
  const { error, value } = createBookmarkSchema.validate(req.body)
  if (error) {
    throw createError.badRequest(error.details[0].message)
  }

  const userId = req.user!.id
  const { title, url, iconUrl, category } = value

  // 检查URL是否已存在
  const existingBookmark = await prisma.bookmark.findFirst({
    where: {
      userId,
      url
    }
  })

  if (existingBookmark) {
    throw createError.conflict('该URL已存在于书签中')
  }

  // 获取当前最大排序值
  const maxSortOrder = await prisma.bookmark.aggregate({
    where: { userId },
    _max: {
      sortOrder: true
    }
  })

  const sortOrder = (maxSortOrder._max.sortOrder || 0) + 1

  // 创建书签
  const bookmark = await prisma.bookmark.create({
    data: {
      userId,
      title,
      url,
      iconUrl: iconUrl || null,
      category: category || 'default',
      sortOrder
    },
    select: {
      id: true,
      title: true,
      url: true,
      iconUrl: true,
      category: true,
      sortOrder: true,
      createdAt: true,
      updatedAt: true
    }
  })

  // 清除相关缓存
  await CacheManager.delPattern(`bookmarks:${userId}*`)
  await CacheManager.del(CacheManager.getUserCacheKey(userId, 'stats'))

  res.status(201).json({
    message: '书签创建成功',
    bookmark
  })
}))

// 更新书签
router.put('/:id', asyncHandler(async (req, res) => {
  // 验证请求数据
  const { error, value } = updateBookmarkSchema.validate(req.body)
  if (error) {
    throw createError.badRequest(error.details[0].message)
  }

  const { id } = req.params
  const userId = req.user!.id
  const updates = value

  // 检查书签是否存在且属于当前用户
  const existingBookmark = await prisma.bookmark.findFirst({
    where: {
      id,
      userId
    }
  })

  if (!existingBookmark) {
    throw createError.notFound('书签不存在')
  }

  // 如果更新URL，检查是否与其他书签冲突
  if (updates.url && updates.url !== existingBookmark.url) {
    const conflictBookmark = await prisma.bookmark.findFirst({
      where: {
        userId,
        url: updates.url,
        id: { not: id }
      }
    })

    if (conflictBookmark) {
      throw createError.conflict('该URL已存在于其他书签中')
    }
  }

  // 更新书签
  const updatedBookmark = await prisma.bookmark.update({
    where: { id },
    data: {
      ...updates,
      updatedAt: new Date()
    },
    select: {
      id: true,
      title: true,
      url: true,
      iconUrl: true,
      category: true,
      sortOrder: true,
      createdAt: true,
      updatedAt: true
    }
  })

  // 清除相关缓存
  await CacheManager.delPattern(`bookmarks:${userId}*`)

  res.json({
    message: '书签更新成功',
    bookmark: updatedBookmark
  })
}))

// 删除书签
router.delete('/:id', asyncHandler(async (req, res) => {
  const { id } = req.params
  const userId = req.user!.id

  // 检查书签是否存在且属于当前用户
  const bookmark = await prisma.bookmark.findFirst({
    where: {
      id,
      userId
    }
  })

  if (!bookmark) {
    throw createError.notFound('书签不存在')
  }

  // 删除书签
  await prisma.bookmark.delete({
    where: { id }
  })

  // 清除相关缓存
  await CacheManager.delPattern(`bookmarks:${userId}*`)
  await CacheManager.del(CacheManager.getUserCacheKey(userId, 'stats'))

  res.json({
    message: '书签删除成功'
  })
}))

// 批量删除书签
router.delete('/', asyncHandler(async (req, res) => {
  const { ids } = req.body
  const userId = req.user!.id

  if (!Array.isArray(ids) || ids.length === 0) {
    throw createError.badRequest('请提供要删除的书签ID列表')
  }

  // 验证所有书签都属于当前用户
  const bookmarks = await prisma.bookmark.findMany({
    where: {
      id: { in: ids },
      userId
    },
    select: { id: true }
  })

  if (bookmarks.length !== ids.length) {
    throw createError.badRequest('部分书签不存在或无权限删除')
  }

  // 批量删除
  const result = await prisma.bookmark.deleteMany({
    where: {
      id: { in: ids },
      userId
    }
  })

  // 清除相关缓存
  await CacheManager.delPattern(`bookmarks:${userId}*`)
  await CacheManager.del(CacheManager.getUserCacheKey(userId, 'stats'))

  res.json({
    message: `成功删除 ${result.count} 个书签`
  })
}))

// 更新书签排序
router.put('/order', asyncHandler(async (req, res) => {
  // 验证请求数据
  const { error, value } = updateOrderSchema.validate(req.body)
  if (error) {
    throw createError.badRequest(error.details[0].message)
  }

  const userId = req.user!.id
  const { bookmarks } = value

  // 验证所有书签都属于当前用户
  const bookmarkIds = bookmarks.map((b: any) => b.id)
  const existingBookmarks = await prisma.bookmark.findMany({
    where: {
      id: { in: bookmarkIds },
      userId
    },
    select: { id: true }
  })

  if (existingBookmarks.length !== bookmarks.length) {
    throw createError.badRequest('部分书签不存在或无权限修改')
  }

  // 批量更新排序
  const updatePromises = bookmarks.map((bookmark: any) =>
    prisma.bookmark.update({
      where: { id: bookmark.id },
      data: { sortOrder: bookmark.sortOrder }
    })
  )

  await Promise.all(updatePromises)

  // 清除相关缓存
  await CacheManager.delPattern(`bookmarks:${userId}*`)

  res.json({
    message: '书签排序更新成功'
  })
}))

// 获取书签分类
router.get('/categories', asyncHandler(async (req, res) => {
  const userId = req.user!.id
  
  // 尝试从缓存获取
  const cacheKey = CacheManager.getUserCacheKey(userId, 'categories')
  let categories = await CacheManager.get(cacheKey)
  
  if (!categories) {
    const result = await prisma.bookmark.groupBy({
      by: ['category'],
      where: { userId },
      _count: {
        category: true
      },
      orderBy: {
        _count: {
          category: 'desc'
        }
      }
    })
    
    categories = result.map(item => ({
      name: item.category,
      count: item._count.category
    }))
    
    // 缓存10分钟
    await CacheManager.set(cacheKey, categories, 600)
  }

  res.json({
    categories
  })
}))

export { router as bookmarkRoutes }